home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 3.2 / Ham Radio Version 3.2 (Chestnut CD-ROMs)(1993).ISO / packet / n17jsrc / command.asm < prev    next >
Assembly Source File  |  1990-12-11  |  11KB  |  500 lines

  1.     .MODEL    MEMMOD,C
  2.     LOCALS
  3.     %MACS
  4.     .LALL
  5.  
  6.     extrn    pwait: far
  7.  
  8.     .DATA
  9.     db    4096 dup(?)
  10. cstack    label    byte
  11.  
  12.  
  13.     .CODE
  14.  
  15. dbase    dw    @Data
  16.  
  17. segoff    struc
  18. offs    dw    ?
  19. segm    dw    ?
  20. segoff    ends
  21.  
  22. main_subr    dw    ?
  23.  
  24. their_8h    dd ?
  25. their_10h    dd ?
  26. their_13h    dd ?
  27. their_1Bh    dd ?
  28. their_21h    dd ?
  29. their_23h    dd ?
  30. their_24h    dd ?
  31. their_28h    dd ?
  32.  
  33. dos_segment    dw ?            ;segment of internal DOS flags
  34. indos_offset    dw ?            ;offset of INDOS flag
  35. errflag_offset    dw ?            ;offset of critical error flag
  36. program_status    db 0            ;popup status
  37. flag_10h    db 0            ;status of interrupt 10h
  38. flag_13h    db 0            ;status of interrupt 13h
  39. zflag        db ?            ;save and restore critical error.
  40. dos_version    db ?            ;dos major version.
  41. main_countdown    db 20
  42. ss_register    dw ?            ;SS register storage
  43. sp_register    dw ?            ;SP register storage
  44. my_psp        dw ?            ;our PSP.
  45. their_psp    dw ?            ;PSP segment storage
  46.  
  47. tick_counter    dw ?
  48. indos_counter    dw ?
  49. errflag_counter    dw ?
  50. status_counter    dw ?
  51. bp_counter    dw ?
  52. main_counter    dw ?
  53.  
  54.  
  55. their_dta    dd    ?
  56. ;
  57. ;------------------------------------------------------------------------------
  58. ;Interrupt 8 handling routine.
  59. ;------------------------------------------------------------------------------
  60. timer:
  61.     pushf                ;call BIOS routine
  62.     call their_8h
  63.     inc tick_counter
  64.     cmp program_status,0        ;are we already running?
  65.     jne timer_status        ;yes, then suspend ticking.
  66.     cmp flag_10h,0            ;video flag set?
  67.     jne timer_exit            ;yes, then exit
  68.     cmp flag_13h,0            ;disk flag set?
  69.     jne timer_exit            ;yes, then exit
  70.     push es                ;save ES and DI
  71.     push di
  72.     mov es,dos_segment        ;check INDOS flag
  73.     mov di,indos_offset
  74.     cmp byte ptr es:[di],0
  75.     jne timer_indos            ;exit if it's set
  76.     mov di,errflag_offset        ;check critical error flag
  77.     cmp byte ptr es:[di],0
  78.     jne timer_errflag        ;exit if it's set
  79.     mov main_subr,offset cycle
  80.     call main            ;call body of program
  81.     pop di
  82.     pop es
  83. timer_exit:
  84.     iret
  85. timer_indos:
  86.     inc indos_counter
  87.     pop di                ;restore registers
  88.     pop es
  89.     iret
  90. timer_errflag:
  91.     inc errflag_counter
  92.     pop di                ;restore registers
  93.     pop es
  94.     iret
  95. timer_status:
  96.     inc status_counter
  97.     iret
  98.  
  99. ;
  100. ;------------------------------------------------------------------------------
  101. ;Interrupt 10h handling routine.
  102. ;------------------------------------------------------------------------------
  103. video:
  104.     pushf                ;push flags onto stack
  105.     inc flag_10h            ;increment flag
  106.     call their_10h            ;call BIOS routine
  107.     dec flag_10h            ;decrement flag
  108.     iret
  109.  
  110. ;
  111. ;------------------------------------------------------------------------------
  112. ;Interrupt 13h handling routine.
  113. ;------------------------------------------------------------------------------
  114. my_13:
  115.     pushf                ;push flags onto stack
  116.     inc flag_13h            ;set 'busy' flag
  117.     call their_13h            ;call BIOS routine
  118.     pushf                ;save output flags
  119.     dec flag_13h            ;clear flag
  120.     popf                ;restore output flags
  121.     retf    2            ;exit without destroying flags
  122.  
  123. ;
  124. ;------------------------------------------------------------------------------
  125. ;Interrupt 28h handling routine.
  126. ;------------------------------------------------------------------------------
  127. my_28:
  128.     pushf                ;call original routine
  129.     call their_28h
  130.     inc bp_counter
  131.     cmp program_status,0        ;are we already running?
  132.     jne bp_exit            ;yes, don't enter it again.
  133.     cmp flag_10h,0            ;video flag set?
  134.     jne bp_exit            ;yes, then exit
  135.     cmp flag_13h,0            ;disk flag set?
  136.     jne bp_exit            ;yes, then exit
  137.     push es                ;save ES and DI
  138.     push di
  139.     mov es,dos_segment        ;check critical error flag
  140.     mov di,errflag_offset
  141.     cmp byte ptr es:[di],0
  142.     pop di                ;clean up the stack
  143.     pop es
  144.     jne bp_errflag
  145.     mov main_subr,offset cycle
  146.     call main            ;call main routine
  147. bp_exit:
  148.     iret                ;done - exit
  149. bp_errflag:
  150.     inc errflag_counter
  151.     iret                ;done - exit
  152.  
  153. ;
  154. ;------------------------------------------------------------------------------
  155. ;Interrupt 21h handling routine.
  156. ;------------------------------------------------------------------------------
  157. my_21:
  158.     pushf                ;save the flags
  159.     or    ah,ah            ;Doing function zero?
  160.     je    jump_to_dos        ;If yes, take the jump
  161.     cmp    ah,4bh            ;Doing EXEC function?
  162.     je    jump_to_dos        ;If yes, take the jump
  163.     popf
  164.  
  165.     pushf
  166.     call    cs:their_21h        ;Do the DOS function
  167.  
  168.     pushf                ;Save the result flags
  169.     cmp    cs:program_status,0    ;are we already running?
  170.     jne    no_recursion        ;yes, don't recurse.
  171.     dec    cs:main_countdown
  172.     jne    no_recursion
  173.     mov    cs:main_countdown,20
  174.     mov    main_subr,offset cycle
  175.     call    main            ;Safe to access disk now
  176. no_recursion:
  177.     popf                ;Recover DOS result flags
  178.  
  179.     sti                ;Must return with interrupts on
  180.     retf    2            ;Return with DOS result flags
  181. jump_to_dos:
  182.     popf
  183.     jmp     cs:their_21h
  184.  
  185. ;
  186. ;------------------------------------------------------------------------------
  187. ;Interrupt 24h handling routine (DOS 3.X only).
  188. ;------------------------------------------------------------------------------
  189. my_24:
  190.     mov al,3            ;fail the call in progress
  191. ioexit:
  192.     iret                ;give control back to DOS
  193.  
  194. cycle:
  195.     xor    ax,ax            ;push a null pointer.
  196.     push    ax
  197.     push    ax
  198.     call    pwait
  199.     add    sp,4
  200.     ret
  201.  
  202. ;
  203. ;------------------------------------------------------------------------------
  204. ;MAIN is the routine called periodically.
  205. ;------------------------------------------------------------------------------
  206. main:
  207.     inc main_counter
  208.     mov program_status,1        ;set program active flag
  209.     cli                ;make sure interrupts are off
  210.     mov ss_register,ss        ;save stack registers
  211.     mov sp_register,sp
  212.     mov ss,cs:dbase            ; establish interrupt data segment
  213.     mov sp,offset cstack
  214.     sti                ;enable interrupts
  215.     push ax
  216.     push bx
  217.     push cx
  218.     push dx
  219.     push si
  220.     push di
  221.     push ds
  222.     push es
  223.     push bp
  224. ;
  225. ;Set DS and ES segment registers.
  226. ;
  227.     push cs                ;set DS to code segment
  228.     pop ds
  229.     assume    ds:seg dos_version
  230. ;
  231. ;Save the current active PSP address and activate this PSP.
  232. ;
  233.     mov zflag,0            ;clear flag
  234.     cmp dos_version,2        ;DOS version 2.X?
  235.     jne main5
  236.     mov es,dos_segment        ;point ES:DI to INDOS
  237.     mov di,indos_offset
  238.     cmp byte ptr es:[di],0        ;INDOS clear?
  239.     je main5            ;yes, then branch
  240.     mov di,errflag_offset        ;point ES:DI to error flag
  241.     cmp byte ptr es:[di],0        ;critical error flag clear?
  242.     jne main5            ;no, then branch
  243.     mov byte ptr es:[di],1        ;set critical error flag manually
  244.     mov zflag,1            ;set change flag
  245. main5:
  246.     mov ah,51h            ;get current PSP segment
  247.     int 21h
  248.     mov their_psp,bx            ;save it
  249.  
  250.     mov ah,50h            ;make this the active PSP
  251.     mov bx,my_psp
  252.     int 21h
  253.  
  254.     cmp zflag,0            ;ZFLAG clear?
  255.     je main6            ;yes, then branch
  256.     mov di,errflag_offset        ;point ES:DI to error flag
  257.     mov byte ptr es:[di],0        ;restore error flag value
  258. main6:
  259. ;
  260. ;Reset the interrupt 1Bh, 23h, and 24h vectors.
  261. ;
  262.     call ioset            ;reset interrupt vectors
  263. ;
  264. ;Save the current dta and subdirectory
  265. ;
  266.     mov    ah,2fh            ;get disk transfer address
  267.     int    21h
  268.     mov    their_dta.segm,es
  269.     mov    their_dta.offs,bx
  270.  
  271. ;
  272. ;Call the commutator loop of net until nothing gets queued up.
  273. ;
  274.     mov    ds,cs:dbase    ; establish interrupt data segment
  275.     assume    ds:nothing
  276.     call    main_subr
  277. ;
  278. ;Restore the current dta and subdirectory
  279. ;
  280.     lds    dx,their_dta
  281.     mov    ah,1ah
  282.     int    21h
  283.  
  284. ;
  285. ;Restore interrupt vectors and former active PSP.
  286. ;
  287.     mov ah,50h            ;restore active PSP label
  288.     mov bx,their_psp
  289.     int 21h
  290.     call ioreset            ;restore interrupt vectors
  291. ;
  292. ;Restore registers and stack before exit.
  293. ;
  294.     pop bp                ;restore registers and exit
  295.     pop es
  296.     pop ds
  297.     pop di
  298.     pop si
  299.     pop dx
  300.     pop cx
  301.     pop bx
  302.     pop ax
  303.     cli                ;interrupts off
  304.     mov ss,ss_register        ;switch to original stack
  305.     mov sp,sp_register
  306.     sti                ;interrupts on
  307.     mov program_status,0        ;clear status flag
  308.     ret
  309.  
  310. ;
  311.  
  312. intset:
  313. ;enter with al = interrupt number, cs:dx = offset of new interrupt,
  314. ;    cs:di -> place to store old interrupt.
  315.  
  316.     push    es            ;get the old interrupt into es:bx
  317.     push    ds            ;now set the new interrupt to ds:dx.
  318.     mov    bx,cs
  319.     mov    ds,bx
  320.  
  321.     mov    ah,35h
  322.     int    21h
  323.     mov    [di].segm,es        ;and store it into ds:di.
  324.     mov    [di].offs,bx
  325.  
  326.     mov    ah,25h
  327.     int    21h
  328.  
  329.     pop    ds
  330.     pop    es
  331.  
  332.     ret
  333.  
  334.  
  335. intreset:
  336. ;enter with al = interrupt number, di -> old interrupt.
  337.     push    ds
  338.     mov    ah,25h
  339.     lds    dx,cs:[di]
  340.     int    21h
  341.     pop    ds
  342.     ret
  343.  
  344.  
  345. ;------------------------------------------------------------------------------
  346. ;IOSET vectors interrupts 1Bh, 23h and 24h to internal handlers.  IORESET
  347. ;restores the original vector values.
  348. ;------------------------------------------------------------------------------
  349. ioset:
  350.     mov    al,1bh
  351.     mov    di,offset their_1Bh
  352.     mov    dx,offset ioexit
  353.     call    intset
  354.  
  355.     mov    al,23h
  356.     mov    di,offset their_23h
  357.     mov    dx,offset ioexit
  358.     call    intset
  359.  
  360.     mov    al,24h
  361.     mov    di,offset their_24h
  362.     mov    dx,offset my_24
  363.     call    intset
  364.  
  365.     ret
  366.  
  367. ;
  368. ioreset:
  369.     mov    al,24h
  370.     mov    di,offset their_24h
  371.     call    intreset
  372.  
  373.     mov    al,23h
  374.     mov    di,offset their_23h
  375.     call    intreset
  376.  
  377.     mov    al,1Bh
  378.     mov    di,offset their_1Bh
  379.     call    intreset
  380.  
  381.     ret
  382.  
  383.  
  384.     public    start_back
  385. start_back    proc
  386. ;
  387. ;Remember our psp.
  388. ;
  389.     mov ah,51h            ;get current PSP segment
  390.     int 21h
  391.     mov my_psp,bx            ;save it
  392.  
  393. ;
  394. ;Determine which version of DOS is running.
  395. ;
  396. init3:
  397.     mov ah,30h            ;DOS function 30h
  398.     int 21h
  399.     mov dos_version,al        ;major version number
  400. ;
  401. ;Get and save the address of the INDOS flag.
  402. ;
  403.     mov ah,34h            ;function 34h
  404.     int 21h                ;get address
  405.     mov dos_segment,es        ;save segment
  406.     mov indos_offset,bx        ;save offset
  407. ;
  408. ;Get and save the address of the critical error flag.
  409. ;
  410.     mov ax,3E80h            ;CMP opcode
  411.     mov cx,2000h            ;max search length
  412.     mov di,bx            ;start at INDOS address
  413. init4:
  414.     repne scasw            ;do the search
  415.     jcxz init5            ;branch if search failed
  416.     cmp byte ptr es:[di+5],0BCh    ;verify this is it
  417.     je found            ;branch if it is
  418.     jmp init4            ;resume loop if it's not
  419. init5:
  420.     mov cx,2000h            ;search again
  421.     inc bx                ;search odd addresses this time
  422.     mov di,bx
  423. init6:
  424.     repne scasw            ;look for the opcode
  425.     jcxz notfound            ;not found if loop expires
  426.     cmp byte ptr es:[di+5],0BCh    ;verify this is it
  427.     je found
  428.     jmp init6
  429. notfound:
  430.     xor    ax,ax
  431.     ret
  432. found:
  433.     mov ax,es:[di]            ;get flag offset address
  434.     mov errflag_offset,ax        ;save it
  435.  
  436. ;
  437. ;Save and replace all required interrupt vectors.
  438. ;
  439.     mov    al,08h
  440.     mov    dx,offset timer
  441.     mov    di,offset their_8h
  442.     call    intset
  443.  
  444.     mov    al,10h
  445.     mov    dx,offset video
  446.     mov    di,offset their_10h
  447.     call    intset
  448.  
  449.     mov    al,13h
  450.     mov    dx,offset my_13
  451.     mov    di,offset their_13h
  452.     call    intset
  453.  
  454.     mov    al,28h
  455.     mov    dx,offset my_28
  456.     mov    di,offset their_28h
  457.     call    intset
  458.  
  459.     mov    al,21h
  460.     mov    dx,offset my_21
  461.     mov    di,offset their_21h
  462.     call    intset
  463.  
  464.     mov    ax,1
  465.     ret
  466. start_back    endp
  467.  
  468.     public    stop_back
  469. stop_back    proc
  470.     mov    cs:program_status,1
  471.  
  472.     mov    al,08h
  473.     mov    di,offset their_8h
  474.     call    intreset
  475.  
  476.     mov    al,10h
  477.     mov    di,offset their_10h
  478.     call    intreset
  479.  
  480.     mov    al,13h
  481.     mov    di,offset their_13h
  482.     call    intreset
  483.  
  484.     mov    al,28h
  485.     mov    di,offset their_28h
  486.     call    intreset
  487.  
  488.     mov    al,21h
  489.     mov    di,offset their_21h
  490.     call    intreset
  491.  
  492.     mov    cs:program_status,0
  493.  
  494.     mov dx,ds
  495.     mov ax,offset tick_counter
  496.     ret
  497. stop_back    endp
  498.  
  499.     end
  500.